// Licensed to Elasticsearch B.V under one or more agreements.
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.
//
// ███╗   ██╗ ██████╗ ████████╗██╗ ██████╗███████╗
// ████╗  ██║██╔═══██╗╚══██╔══╝██║██╔════╝██╔════╝
// ██╔██╗ ██║██║   ██║   ██║   ██║██║     █████╗
// ██║╚██╗██║██║   ██║   ██║   ██║██║     ██╔══╝
// ██║ ╚████║╚██████╔╝   ██║   ██║╚██████╗███████╗
// ╚═╝  ╚═══╝ ╚═════╝    ╚═╝   ╚═╝ ╚═════╝╚══════╝
// ------------------------------------------------
//
// This file is automatically generated.
// Please do not edit these files manually.
//
// ------------------------------------------------

#nullable restore

using Elastic.Clients.Elasticsearch.Fluent;
using Elastic.Clients.Elasticsearch.Serialization;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Elastic.Clients.Elasticsearch.Core.Search;

public sealed partial class CompletionSuggester
{
	[JsonInclude, JsonPropertyName("analyzer")]
	public string? Analyzer { get; set; }

	/// <summary>
	/// <para>A value, geo point object, or a geo hash string to filter or boost the suggestion on.</para>
	/// </summary>
	[JsonInclude, JsonPropertyName("contexts")]
	public IDictionary<Elastic.Clients.Elasticsearch.Field, ICollection<Elastic.Clients.Elasticsearch.Core.Search.CompletionContext>>? Contexts { get; set; }
	[JsonInclude, JsonPropertyName("field")]
	public Elastic.Clients.Elasticsearch.Field Field { get; set; }

	/// <summary>
	/// <para>Enables fuzziness, meaning you can have a typo in your search and still get results back.</para>
	/// </summary>
	[JsonInclude, JsonPropertyName("fuzzy")]
	public Elastic.Clients.Elasticsearch.Core.Search.SuggestFuzziness? Fuzzy { get; set; }

	/// <summary>
	/// <para>A regex query that expresses a prefix as a regular expression.</para>
	/// </summary>
	[JsonInclude, JsonPropertyName("regex")]
	public Elastic.Clients.Elasticsearch.Core.Search.RegexOptions? Regex { get; set; }
	[JsonInclude, JsonPropertyName("size")]
	public int? Size { get; set; }

	/// <summary>
	/// <para>Whether duplicate suggestions should be filtered out.</para>
	/// </summary>
	[JsonInclude, JsonPropertyName("skip_duplicates")]
	public bool? SkipDuplicates { get; set; }

	public static implicit operator FieldSuggester(CompletionSuggester completionSuggester) => Core.Search.FieldSuggester.Completion(completionSuggester);
}

public sealed partial class CompletionSuggesterDescriptor<TDocument> : SerializableDescriptor<CompletionSuggesterDescriptor<TDocument>>
{
	internal CompletionSuggesterDescriptor(Action<CompletionSuggesterDescriptor<TDocument>> configure) => configure.Invoke(this);

	public CompletionSuggesterDescriptor() : base()
	{
	}

	private string? AnalyzerValue { get; set; }
	private IDictionary<Elastic.Clients.Elasticsearch.Field, ICollection<Elastic.Clients.Elasticsearch.Core.Search.CompletionContext>>? ContextsValue { get; set; }
	private Elastic.Clients.Elasticsearch.Field FieldValue { get; set; }
	private Elastic.Clients.Elasticsearch.Core.Search.SuggestFuzziness? FuzzyValue { get; set; }
	private SuggestFuzzinessDescriptor FuzzyDescriptor { get; set; }
	private Action<SuggestFuzzinessDescriptor> FuzzyDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.Core.Search.RegexOptions? RegexValue { get; set; }
	private RegexOptionsDescriptor RegexDescriptor { get; set; }
	private Action<RegexOptionsDescriptor> RegexDescriptorAction { get; set; }
	private int? SizeValue { get; set; }
	private bool? SkipDuplicatesValue { get; set; }

	public CompletionSuggesterDescriptor<TDocument> Analyzer(string? analyzer)
	{
		AnalyzerValue = analyzer;
		return Self;
	}

	/// <summary>
	/// <para>A value, geo point object, or a geo hash string to filter or boost the suggestion on.</para>
	/// </summary>
	public CompletionSuggesterDescriptor<TDocument> Contexts(Func<FluentDictionary<Elastic.Clients.Elasticsearch.Field, ICollection<Elastic.Clients.Elasticsearch.Core.Search.CompletionContext>>, FluentDictionary<Elastic.Clients.Elasticsearch.Field, ICollection<Elastic.Clients.Elasticsearch.Core.Search.CompletionContext>>> selector)
	{
		ContextsValue = selector?.Invoke(new FluentDictionary<Elastic.Clients.Elasticsearch.Field, ICollection<Elastic.Clients.Elasticsearch.Core.Search.CompletionContext>>());
		return Self;
	}

	public CompletionSuggesterDescriptor<TDocument> Field(Elastic.Clients.Elasticsearch.Field field)
	{
		FieldValue = field;
		return Self;
	}

	public CompletionSuggesterDescriptor<TDocument> Field<TValue>(Expression<Func<TDocument, TValue>> field)
	{
		FieldValue = field;
		return Self;
	}

	/// <summary>
	/// <para>Enables fuzziness, meaning you can have a typo in your search and still get results back.</para>
	/// </summary>
	public CompletionSuggesterDescriptor<TDocument> Fuzzy(Elastic.Clients.Elasticsearch.Core.Search.SuggestFuzziness? fuzzy)
	{
		FuzzyDescriptor = null;
		FuzzyDescriptorAction = null;
		FuzzyValue = fuzzy;
		return Self;
	}

	public CompletionSuggesterDescriptor<TDocument> Fuzzy(SuggestFuzzinessDescriptor descriptor)
	{
		FuzzyValue = null;
		FuzzyDescriptorAction = null;
		FuzzyDescriptor = descriptor;
		return Self;
	}

	public CompletionSuggesterDescriptor<TDocument> Fuzzy(Action<SuggestFuzzinessDescriptor> configure)
	{
		FuzzyValue = null;
		FuzzyDescriptor = null;
		FuzzyDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>A regex query that expresses a prefix as a regular expression.</para>
	/// </summary>
	public CompletionSuggesterDescriptor<TDocument> Regex(Elastic.Clients.Elasticsearch.Core.Search.RegexOptions? regex)
	{
		RegexDescriptor = null;
		RegexDescriptorAction = null;
		RegexValue = regex;
		return Self;
	}

	public CompletionSuggesterDescriptor<TDocument> Regex(RegexOptionsDescriptor descriptor)
	{
		RegexValue = null;
		RegexDescriptorAction = null;
		RegexDescriptor = descriptor;
		return Self;
	}

	public CompletionSuggesterDescriptor<TDocument> Regex(Action<RegexOptionsDescriptor> configure)
	{
		RegexValue = null;
		RegexDescriptor = null;
		RegexDescriptorAction = configure;
		return Self;
	}

	public CompletionSuggesterDescriptor<TDocument> Size(int? size)
	{
		SizeValue = size;
		return Self;
	}

	/// <summary>
	/// <para>Whether duplicate suggestions should be filtered out.</para>
	/// </summary>
	public CompletionSuggesterDescriptor<TDocument> SkipDuplicates(bool? skipDuplicates = true)
	{
		SkipDuplicatesValue = skipDuplicates;
		return Self;
	}

	protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings)
	{
		writer.WriteStartObject();
		if (!string.IsNullOrEmpty(AnalyzerValue))
		{
			writer.WritePropertyName("analyzer");
			writer.WriteStringValue(AnalyzerValue);
		}

		if (ContextsValue is not null)
		{
			writer.WritePropertyName("contexts");
			JsonSerializer.Serialize(writer, ContextsValue, options);
		}

		writer.WritePropertyName("field");
		JsonSerializer.Serialize(writer, FieldValue, options);
		if (FuzzyDescriptor is not null)
		{
			writer.WritePropertyName("fuzzy");
			JsonSerializer.Serialize(writer, FuzzyDescriptor, options);
		}
		else if (FuzzyDescriptorAction is not null)
		{
			writer.WritePropertyName("fuzzy");
			JsonSerializer.Serialize(writer, new SuggestFuzzinessDescriptor(FuzzyDescriptorAction), options);
		}
		else if (FuzzyValue is not null)
		{
			writer.WritePropertyName("fuzzy");
			JsonSerializer.Serialize(writer, FuzzyValue, options);
		}

		if (RegexDescriptor is not null)
		{
			writer.WritePropertyName("regex");
			JsonSerializer.Serialize(writer, RegexDescriptor, options);
		}
		else if (RegexDescriptorAction is not null)
		{
			writer.WritePropertyName("regex");
			JsonSerializer.Serialize(writer, new RegexOptionsDescriptor(RegexDescriptorAction), options);
		}
		else if (RegexValue is not null)
		{
			writer.WritePropertyName("regex");
			JsonSerializer.Serialize(writer, RegexValue, options);
		}

		if (SizeValue.HasValue)
		{
			writer.WritePropertyName("size");
			writer.WriteNumberValue(SizeValue.Value);
		}

		if (SkipDuplicatesValue.HasValue)
		{
			writer.WritePropertyName("skip_duplicates");
			writer.WriteBooleanValue(SkipDuplicatesValue.Value);
		}

		writer.WriteEndObject();
	}
}

public sealed partial class CompletionSuggesterDescriptor : SerializableDescriptor<CompletionSuggesterDescriptor>
{
	internal CompletionSuggesterDescriptor(Action<CompletionSuggesterDescriptor> configure) => configure.Invoke(this);

	public CompletionSuggesterDescriptor() : base()
	{
	}

	private string? AnalyzerValue { get; set; }
	private IDictionary<Elastic.Clients.Elasticsearch.Field, ICollection<Elastic.Clients.Elasticsearch.Core.Search.CompletionContext>>? ContextsValue { get; set; }
	private Elastic.Clients.Elasticsearch.Field FieldValue { get; set; }
	private Elastic.Clients.Elasticsearch.Core.Search.SuggestFuzziness? FuzzyValue { get; set; }
	private SuggestFuzzinessDescriptor FuzzyDescriptor { get; set; }
	private Action<SuggestFuzzinessDescriptor> FuzzyDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.Core.Search.RegexOptions? RegexValue { get; set; }
	private RegexOptionsDescriptor RegexDescriptor { get; set; }
	private Action<RegexOptionsDescriptor> RegexDescriptorAction { get; set; }
	private int? SizeValue { get; set; }
	private bool? SkipDuplicatesValue { get; set; }

	public CompletionSuggesterDescriptor Analyzer(string? analyzer)
	{
		AnalyzerValue = analyzer;
		return Self;
	}

	/// <summary>
	/// <para>A value, geo point object, or a geo hash string to filter or boost the suggestion on.</para>
	/// </summary>
	public CompletionSuggesterDescriptor Contexts(Func<FluentDictionary<Elastic.Clients.Elasticsearch.Field, ICollection<Elastic.Clients.Elasticsearch.Core.Search.CompletionContext>>, FluentDictionary<Elastic.Clients.Elasticsearch.Field, ICollection<Elastic.Clients.Elasticsearch.Core.Search.CompletionContext>>> selector)
	{
		ContextsValue = selector?.Invoke(new FluentDictionary<Elastic.Clients.Elasticsearch.Field, ICollection<Elastic.Clients.Elasticsearch.Core.Search.CompletionContext>>());
		return Self;
	}

	public CompletionSuggesterDescriptor Field(Elastic.Clients.Elasticsearch.Field field)
	{
		FieldValue = field;
		return Self;
	}

	public CompletionSuggesterDescriptor Field<TDocument, TValue>(Expression<Func<TDocument, TValue>> field)
	{
		FieldValue = field;
		return Self;
	}

	public CompletionSuggesterDescriptor Field<TDocument>(Expression<Func<TDocument, object>> field)
	{
		FieldValue = field;
		return Self;
	}

	/// <summary>
	/// <para>Enables fuzziness, meaning you can have a typo in your search and still get results back.</para>
	/// </summary>
	public CompletionSuggesterDescriptor Fuzzy(Elastic.Clients.Elasticsearch.Core.Search.SuggestFuzziness? fuzzy)
	{
		FuzzyDescriptor = null;
		FuzzyDescriptorAction = null;
		FuzzyValue = fuzzy;
		return Self;
	}

	public CompletionSuggesterDescriptor Fuzzy(SuggestFuzzinessDescriptor descriptor)
	{
		FuzzyValue = null;
		FuzzyDescriptorAction = null;
		FuzzyDescriptor = descriptor;
		return Self;
	}

	public CompletionSuggesterDescriptor Fuzzy(Action<SuggestFuzzinessDescriptor> configure)
	{
		FuzzyValue = null;
		FuzzyDescriptor = null;
		FuzzyDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>A regex query that expresses a prefix as a regular expression.</para>
	/// </summary>
	public CompletionSuggesterDescriptor Regex(Elastic.Clients.Elasticsearch.Core.Search.RegexOptions? regex)
	{
		RegexDescriptor = null;
		RegexDescriptorAction = null;
		RegexValue = regex;
		return Self;
	}

	public CompletionSuggesterDescriptor Regex(RegexOptionsDescriptor descriptor)
	{
		RegexValue = null;
		RegexDescriptorAction = null;
		RegexDescriptor = descriptor;
		return Self;
	}

	public CompletionSuggesterDescriptor Regex(Action<RegexOptionsDescriptor> configure)
	{
		RegexValue = null;
		RegexDescriptor = null;
		RegexDescriptorAction = configure;
		return Self;
	}

	public CompletionSuggesterDescriptor Size(int? size)
	{
		SizeValue = size;
		return Self;
	}

	/// <summary>
	/// <para>Whether duplicate suggestions should be filtered out.</para>
	/// </summary>
	public CompletionSuggesterDescriptor SkipDuplicates(bool? skipDuplicates = true)
	{
		SkipDuplicatesValue = skipDuplicates;
		return Self;
	}

	protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings)
	{
		writer.WriteStartObject();
		if (!string.IsNullOrEmpty(AnalyzerValue))
		{
			writer.WritePropertyName("analyzer");
			writer.WriteStringValue(AnalyzerValue);
		}

		if (ContextsValue is not null)
		{
			writer.WritePropertyName("contexts");
			JsonSerializer.Serialize(writer, ContextsValue, options);
		}

		writer.WritePropertyName("field");
		JsonSerializer.Serialize(writer, FieldValue, options);
		if (FuzzyDescriptor is not null)
		{
			writer.WritePropertyName("fuzzy");
			JsonSerializer.Serialize(writer, FuzzyDescriptor, options);
		}
		else if (FuzzyDescriptorAction is not null)
		{
			writer.WritePropertyName("fuzzy");
			JsonSerializer.Serialize(writer, new SuggestFuzzinessDescriptor(FuzzyDescriptorAction), options);
		}
		else if (FuzzyValue is not null)
		{
			writer.WritePropertyName("fuzzy");
			JsonSerializer.Serialize(writer, FuzzyValue, options);
		}

		if (RegexDescriptor is not null)
		{
			writer.WritePropertyName("regex");
			JsonSerializer.Serialize(writer, RegexDescriptor, options);
		}
		else if (RegexDescriptorAction is not null)
		{
			writer.WritePropertyName("regex");
			JsonSerializer.Serialize(writer, new RegexOptionsDescriptor(RegexDescriptorAction), options);
		}
		else if (RegexValue is not null)
		{
			writer.WritePropertyName("regex");
			JsonSerializer.Serialize(writer, RegexValue, options);
		}

		if (SizeValue.HasValue)
		{
			writer.WritePropertyName("size");
			writer.WriteNumberValue(SizeValue.Value);
		}

		if (SkipDuplicatesValue.HasValue)
		{
			writer.WritePropertyName("skip_duplicates");
			writer.WriteBooleanValue(SkipDuplicatesValue.Value);
		}

		writer.WriteEndObject();
	}
}